//=============================================================================
// Claw - Tripmine launcher
//=============================================================================
class TFClaw extends ChaosWeapon config(user);

#exec OBJ LOAD FILE=TripMineA.ukx

// sounds
var sound Proxylauncher_select[5];
var sound Minelauncher_select1;


// used to hold the ChaosWeapon Option mode
var bool bkamiInit, bKamiLockOut;
var float KamiFireTime, KamiInitTime;

var bool bCanPlayFiringAnim;     // Var use to delay the firing effect when you are controlling a proxy

//=============================================================================
// replication
//=============================================================================
replication
{
    // Things the server should send to the client.
    reliable if( Role==ROLE_Authority )
       bCanPlayFiringAnim;
}


//=============================================================================
// AI Interface
//============================================================================
function float GetAIRating()
{
	local Bot B;
	local float EnemyDist;
	local vector EnemyDir;

	B = Bot(Instigator.Controller);
	if ( (B == None))
		return AIRating;
    // If the bot has a kami started do not switch back to the claw unless it has to
    if (bkamiInit)
      return - 0.5;
    // If bot is close to its objective and does not have the needler ammo out, this is not a bad weapon
    if (B.Enemy == none && count <=1)
	{
		if (B.Formation() && B.Squad.SquadObjective != None && B.Squad.SquadObjective.BotNearObjective(B))
			return 1.1;
    }
    if (B.Enemy == None ) // for log warning
		return AIRating;

	// if retreating, favor this weapon
	EnemyDir = B.Enemy.Location - Instigator.Location;
	EnemyDist = VSize(EnemyDir);
	if ( EnemyDist > 1500 )
		return 0.1;
	if ( B.IsRetreating() )
		return (AIRating + 0.4);
	if ( -1 * EnemyDir.Z > EnemyDist )
		return AIRating + 0.1;
	return AIRating;
}

/* BestMode()
choose between regular or alt-fire
*/
function byte BestMode()
{
    local bot B;
    B = Bot(Instigator.Controller);
    //stolen from mine layer
    if (B!=none && B.Enemy == none && count <=1)
	{
		if (B.Formation() && B.Squad.SquadObjective != None && B.Squad.SquadObjective.BotNearObjective(B))
		{
		   //If proxies are loaded prefer sleepers if we are near an objective and no enemy in sight
		   if (count == 0)
		   {
              if ( FRand() < 0.8 )
		         return 1;
	          return 0;
           }
           else  // If its the fire minds...meh :)
           {
               if ( FRand() < 0.6 )
		          return 1;
	           return 0;
           }
		}
	}
    // Check to se if wee should be using a differet ammo every so often but not when we are attacking
    if ((B.Skill <= 3 && Level.TimeSeconds + 2.0 > BotLastSpecialAmmoCheck)
    || (B.Skill > 3 && Level.TimeSeconds + 1.0 > BotLastSpecialAmmoCheck))
    {
         BotPickSpecialAmmo(B);
         BotLastSpecialAmmoCheck = Level.TimeSeconds;
         // We will use the CWO if we have laserminds out, or if the bot is low on health and its enemy is close and it has needles..
         if (count == 1 && B.Skill > 1)
             ChaosWeaponOption();
         else if (Count==2 && !bkamiInit && !Level.Game.IsA('ChaosDuel') && !Level.Game.IsA('Invasion')&& B.Pawn != None &&
           B.Pawn.Health < 40 && B.Skill > 1 && Vsize(B.Enemy.Location - B.Pawn.Location) < 600 &&
           Ammo[0].AmmoAmount >=4)
           {
              bkamiInit=true;
              ChaosWeaponOption();
           }
    }
    // For proxies or firemines prefer normal.
	if (Count != 2)
    {
       if (FRand() < 0.8 )
	 	  return 0;
	   else
          return 1;
     }
     // For needles use primary if they are clos, secondary if they are retreating
     else
     {
        if( B.Enemy != None && VSize(B.Enemy.Location - Instigator.Location) < 1000)
   	 	   return 0;
	    else if (B.IsRetreating())
           return 1;
        else if (FRand() < 0.5 )
           return 0;
        else
           return 1;
     }
}


function BotPickSpecialAmmo(Bot B)
{
   if (Count == 0)
      if (!HasOtherAmmo())
        Return; // we only have the default ammo return

    // if the bot is attacking/Retreating  make sure its using the needle ammo
    if (B.Squad.CurrentOrders == 'Attack' || B.IsRetreating())
    {
       if (Count != 2)
          if (HasSpecificAmmo(2))
               SwitchFireMode(2);
        return;
    }
    // Freelancing..use proxys
    if (B.Squad.bFreelance)
    {
        if (Count != 0)
          if (HasSpecificAmmo(0))
               SwitchFireMode(0);
        return;
    }
    // If the bot is on Defense lets use either fire or proxies to slow down the enemies
    if (B.Squad.CurrentOrders == 'defend')
       if (Count == 2)
           ChangeAmmo();
}

function float SuggestAttackStyle()
{
	local Bot B;
	local float EnemyDist;

	B = Bot(Instigator.Controller);
	if ( (B == None) || (B.Enemy == None) )
		return 0.4;

	EnemyDist = VSize(B.Enemy.Location - Instigator.Location);
	// Rush them so long as we dont have fireammo loaded
    if (Count != 1  && EnemyDist > 1500 )
		return 1.0;
	// They are getting closer but still rush if we dont have firemines
    if (Count != 1 && EnemyDist > 800 )
		return 0.4;
	return -0.1;
}

function float SuggestDefenseStyle()
{
	local Bot B;

	B = Bot(Instigator.Controller);
	if ( (B == None) || (B.Enemy == None) )
		return 0;
    // back up if we have the fire minds loaded
	if (count == 1 && VSize(B.Enemy.Location - Instigator.Location) < 1600 )
		return -0.6;
	return 0;
}

function bool ShouldFireWithoutTarget()
{
    // If bots dont have needlers loaded they yes fire with out target
    if (count != 2)
       return true;
    else
       Return false;
}
//=============================================================================
// End AI Interface
//============================================================================


function DropFrom(vector StartLocation)
{
   // Don't let them throw the weapon if the Kami is active
    if (bKamiLockOut && Instigator != None && Instigator.Health > 0)
        return;
    else
        Super.DropFrom(StartLocation);
}


simulated function Tick(Float DeltaTime)
{
   if (bKamiLockOut)
   {
     if (Level.TimeSeconds > KamiFireTime)
         bKamiLockOut=false;
   }
   else if (bkamiInit)
   {
      if (Level.TimeSeconds > KamiInitTime)
      {
         bkamiInit=false;
         if (Instigator.Controller != None)
            PlayerController(Instigator.Controller).ClientMessage("Kami move Timer Reset.");
      }
   }
   super.Tick(DeltaTime);
}


exec function ChaosWeaponOption()
{
	Local ClawFiremineProj LTP;
//    local Mine Proxy, ClosestProxy;
//    local int iMax;
//    local int dist, ClosestProxyDist;
//    local PlayerController Possessor;
    local bot B;
    if ( Role == ROLE_Authority )
        if ( Level.Game.IsA('ChaosDuel') &&
        (Level.Game.IsInState('WaitingForNextRound') || Level.Game.IsInState('PendingRound')) )
           return;
    // Make sure if we have inted kami player can not switch AWO featrers
    if (bKamiLockOut)
      return;


	if (Instigator != None && Instigator.Controller != None)
      B = Bot(Instigator.Controller);
    switch (Count)
    {
          Case 1:
             // Laser Trip Mines, find the instigator and destory it
             foreach DynamicActors(class'ClawFiremineProj', LTP)
             {
                 // For bots check to see if their enmy is close, if so blow up the mine if the mine is attached
                 if ( B != None && B.Enemy != None && Instigator != None && (LTP.Instigator == Instigator
                 || LTP.InstigatorController == Instigator.Controller))
                 {
                     if (LTP.bInitialized  && Vsize(LTP.Location - B.Enemy.Location) < 200 )
                         LTP.Destroy();
                 }
                 // This deonates the Laser Mine if it has attached for human players
                 else If (Instigator != None &&  (LTP.Instigator == Instigator
                 || LTP.InstigatorController == Instigator.Controller))
                 {
                     if (LTP.bInitialized)
                        LTP.Destroy();
                 }
             }
          Break;
    }
}

// Needed this so we can avoid ANs as this was needing projectiles speed
// and our proxies are not projectiles!
function bool CanAttack(Actor Other)
{
    local float Dist, CheckDist;
    local vector HitLocation, HitNormal,X,Y,Z, projStart;
    local actor HitActor;
    local int m;
	local bool bInstantHit;

    if ( (Instigator == None) || (Instigator.Controller == None) )
        return false;

    // check that target is within range
    Dist = VSize(Instigator.Location - Other.Location);
    if ( (Dist > FireMode[0].MaxRange()) && (Dist > FireMode[1].MaxRange()) )
        return false;

    // check that can see target
    if ( !Instigator.Controller.LineOfSightTo(Other) )
        return false;

    for (m = 0; m < NUM_FIRE_MODES; m++)
    {
		if ( FireMode[m].bInstantHit )
			bInstantHit = true;
		else
		{    // here was where they wantd projectile speed..so I guessed at 400 as
		    // Proxies are not projectiles
			CheckDist = FMax(CheckDist, 0.5 * 400);
	        CheckDist = FMax(CheckDist, 300);
	        CheckDist = FMin(CheckDist, VSize(Other.Location - Location));
		}
	}
    // check that would hit target, and not a friendly
    GetAxes(Instigator.Controller.Rotation, X,Y,Z);
    projStart = GetFireStart(X,Y,Z);
    if ( bInstantHit )
        HitActor = Trace(HitLocation, HitNormal, Other.Location + Other.CollisionHeight * vect(0,0,0.8), projStart, true);
    else
    {
        // for non-instant hit, only check partial path (since others may move out of the way)
        HitActor = Trace(HitLocation, HitNormal,
                projStart + CheckDist * Normal(Other.Location + Other.CollisionHeight * vect(0,0,0.8) - Location),
                projStart, true);
    }

     //  epic 3321 code
     if ( (HitActor == None) || (HitActor == Other) )
		return true;
	if ( Pawn(HitActor) == None )
		return !HitActor.BlocksShotAt(Other);
	if ( (Pawn(HitActor).Controller == None) || !Instigator.Controller.SameTeamAs(Pawn(HitActor).Controller) )
        return true;

    return false;
}

// use this to change tha rate of the idle animation???
simulated function PlayIdle()
{
   if (FRand()>0.25) // && AnimSequence != 'Idle')
      PlayAnim('Still',0.6,0.9);
   else
      PlayAnim('Idle',0.1, 0.9);
}

simulated function bool PutDown()
{
    bkamiInit=false;
    return super.PutDown();
}


// needed to cut and paste this from parent so we can play a random sound
simulated function BringUp(optional Weapon PrevWeapon) {
    bkamiInit=false;
    // check for proper 1st mesh here
    if (Count == 1)
    {
        LinkMesh(SkeletalMesh'TripMineA.Chaos_minel_firem_1st');
        Skins[0]=Shader'TFMedia.Mines.Minelauncher_Shade';
        Skins[1]=Shader'TFMedia.Mines.Fireminepickup_Shade';
        Skins[2]=Shader'TFMedia.Mines.Firemine_Shade';
    }
	Super.BringUp();

}

defaultproperties
{
     Proxylauncher_select(0)=Sound'TFMedia.Proxy.Proxylauncher_select01'
     Proxylauncher_select(1)=Sound'TFMedia.Proxy.Proxylauncher_select02'
     Proxylauncher_select(2)=Sound'TFMedia.Proxy.Proxylauncher_select03'
     Proxylauncher_select(3)=Sound'TFMedia.Proxy.Proxylauncher_select04'
     Proxylauncher_select(4)=Sound'TFMedia.Proxy.Proxylauncher_select05'
     Minelauncher_select1=Sound'TFMedia.Lasermine.lasermine_select'
     bCanPlayFiringAnim=True
     MyParentClass=Class'taskforces.TFClaw'
     AmmoType(0)=(AmmoClass=Class'taskforces.ClawFiremineAmmo',Attachment=Class'taskforces.ClawFiremineAttachment',Pickup=Class'taskforces.ClawFireminePickup',bSuperAmmoLimit=True)
     FireModeClass(0)=Class'taskforces.ClawFire'
     FireModeClass(1)=Class'taskforces.ClawAltFire'
     PutDownAnim="PutDown"
     IdleAnimRate=0.100000
     SelectSound=Sound'WeaponSounds.FlakCannon.SwitchToFlakCannon'
     SelectForce="SwitchToFlakCannon"
     AIRating=0.550000
     CurrentRating=0.550000
     EffectOffset=(X=100.000000,Y=32.000000,Z=-20.000000)
     DisplayFOV=60.000000
     HudColor=(B=255,G=0,R=64)
     SmallViewOffset=(X=-10.000000,Y=6.000000,Z=-22.000000)
     CenteredOffsetY=-20.000000
     CustomCrosshair=14
     CustomCrossHairColor=(G=0,R=0)
     CustomCrossHairTextureName="TFMedia.XHairs.Claw"
     InventoryGroup=3
     GroupOffset=2
     PickupClass=Class'taskforces.ClawFireminePickup'
     PlayerViewOffset=(X=-24.000000,Y=-2.000000,Z=-16.000000)
     PlayerViewPivot=(Yaw=-16383)
     BobDamping=2.200000
     AttachmentClass=Class'taskforces.ClawFiremineAttachment'
     IconMaterial=Texture'TFMedia.Icons.Claw'
     IconCoords=(X1=27,Y1=10,X2=101,Y2=87)
     ItemName="Trip Mines"
     Mesh=SkeletalMesh'TripMineA.Chaos_minel_firem_1st'
     UV2Texture=Shader'XGameShaders.WeaponShaders.WeaponEnvShader'
     AmmoRegenAmount(0)=2
     SkillCost=50
     StationDmgModifier=0
}
